import java.util.PriorityQueue;

class MyTimerTask implements Comparable<MyTimerTask>{
     private Runnable task;
     private long time;

     public MyTimerTask(Runnable task,long time) {
          this.task = task;
          this.time = time;
     }

     public long getTime() {
          return time;
     }

     public Runnable getTask() {
          return task;
     }

     @Override
     public int compareTo(MyTimerTask o) {
          return (int)(this.time - o.time);
          //return (int)(o.time - this.time);
     }

     public void run() {
          task.run();
     }
}
class MyTimer {
     private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();

     public void schedule(Runnable task,long delay) throws InterruptedException {
          synchronized (this) {
               queue.offer(new MyTimerTask(task, System.currentTimeMillis() + delay));
               this.notify();
          }
     }

          public MyTimer(){
               Thread t = new Thread(()->{
                  try {
                       while(true) {
                            synchronized (this) {
                                 while(queue.isEmpty()) {
                                      this.wait();
                                 }
                                 MyTimerTask task = queue.peek();
                                 if (System.currentTimeMillis() < task.getTime()) {
                                      this.wait(task.getTime() - System.currentTimeMillis());
                                 }else {
                                      task.run();
                                      queue.poll();
                                 }
                            }
                       }
                  } catch (InterruptedException e) {
                       throw new RuntimeException(e);
                  }
               });
               t.start();
          }

     }


public class demo19 {
     public static void main(String[] args) throws InterruptedException {
          MyTimer timer = new MyTimer();
          timer.schedule(new Runnable() {
               @Override
               public void run() {
                    System.out.println("hello 3000");
               }
          },3000);
          timer.schedule(new Runnable() {
               @Override
               public void run() {
                    System.out.println("hello 2000");
               }
          },2000);
          timer.schedule(new Runnable() {
               @Override
               public void run() {
                    System.out.println("hello 1000");
               }
          },1000);
     }
}
